#if UNITY_WEBGL 
using System;
using System.Collections.Generic;
using System.IO;
using FibMatrix.IO;
using FM_Mono;
using UnityEngine;
using WeChatWASM;

[IgnoreGen]
public class WechatStorageImpl:StorageImplBase, IReadWriteStorageImpl
{
    private const string ACCESS_OK = "access:ok";
    private const string COPY_OK = "copy:ok";
    
    private WXFileSystemManager _fs = WX.GetFileSystemManager();
    // private string _streamingAssetPathPrefix;

    /// <summary>
    /// </summary>
    /// <param name="isPackage"></param>
    public WechatStorageImpl(string persistPath) : base(persistPath)
    {
        
    }
    
    public bool Exists(string path, bool isFile = true)
    {
        var fullPath = GetFullPath(path);
        return _fs.AccessSync(fullPath) == ACCESS_OK;
    }

    public byte[] ReadAllBytes(string path)
    {
        string fullPath = GetFullPath(path);
        Debug.Log($"WechatStorageImpl ReadAllBytes path:{path} fullPath:{fullPath}");
        return _fs.ReadFileSync(fullPath);
    }

    public string ReadAllText(string path)
    {
        string fullPath = GetFullPath(path);
        Debug.Log($"WechatStorageImpl ReadAllText path:{path} fullPath: {fullPath}");
        return _fs.ReadFileSync(fullPath, "utf8");
    }

    public void CreateDirectory(string path)
    {
        string fullPath = GetFullPath(path);
       _fs.MkdirSync(fullPath, true);
    }

    public void WriteAllBytes(string path, byte[] bytes)
    {
        string fullPath = GetFullPath(path);
        _fs.WriteFileSync(fullPath, bytes, "binary");
    }

    public void WriteAllText(string path, string content)
    {
        string fullPath = GetFullPath(path);
        _fs.WriteFileSync(fullPath, content);
    }

    public void DeleteFile(string path)
    {
        string fullPath = GetFullPath(path);
        _fs.UnlinkSync(fullPath);
    }

    public void DeleteDirectory(string path, bool recursive)
    {
        string fullPath = GetFullPath(path);
        _fs.RmdirSync(fullPath, recursive);
    }

    public void CopyFile(string srcPath, string dstPath, bool overwrite)
    {
        string srcFullPath = GetFullPath(srcPath);
        string dstFullPath = GetFullPath(dstPath);
        _fs.CopyFileSync(srcFullPath, dstFullPath);
    }

    public void MoveFile(string srcPath, string dstPath)
    {
        string srcFullPath = GetFullPath(srcPath);
        string dstFullPath = GetFullPath(dstPath);
        if (_fs.CopyFileSync(srcFullPath, dstFullPath) == COPY_OK)
        {
            _fs.UnlinkSync(srcFullPath);
        }
    }

    public void MoveDirectory(string srcPath, string dstPath)
    {
        throw new NotImplementedException();
    }

    public Stream CreateFile(string path)
    {
        return Open(path, FileMode.Create, FileAccess.ReadWrite);
    }

    public Stream Open(string path, FileMode mode, FileAccess access)
    {
        string flag;
        switch (mode)
        {
            case FileMode.CreateNew:
                flag = "wx";
                break;
            case FileMode.Create:
                flag = "wx+";
                break;
            case FileMode.Append:
                flag = "as";
                break;
            case FileMode.Open:
                flag = access == FileAccess.Read ? "r" : "r+";
                break;
            case FileMode.Truncate:
                flag = "w";
                break;
            case FileMode.OpenOrCreate:
                flag = "as+";
                break;
            default:
                flag = "r+";
                break;
        }
        string fullPath = GetFullPath(path);
        int fd = _fs.OpenStreamSync(fullPath, flag, out var length);
        if (fd >= 0)
        {
            var stream = new WechatFileStream(_fs, fd, length);
            if (mode == FileMode.OpenOrCreate)
            {
                stream.Position = 0;
            }

            return stream;
        }

        return null;
    }
    
    public void ListDirectory(string path, bool recursive, StatMode mode, Action<string> visitFunc)
    {
        string fullPath = GetFullPath(path);
        var res = _fs.StatSync(fullPath, recursive);
        if (string.IsNullOrEmpty(res.errMsg))
        {
            foreach (var statInfo in res.stats)
            {
                bool canVisit = true;
                switch (mode)
                {
                    case StatMode.File:
                        canVisit = statInfo.stats.IsFile();
                        break;
                    case StatMode.Directory:
                        canVisit = statInfo.stats.IsDirectory();
                        break;
                }

                if (canVisit)
                {
                    visitFunc?.Invoke(statInfo.path);
                }
            }
        }
    }

    public Stream OpenRead(string filePath)
    {
        return Open(filePath, FileMode.Open, FileAccess.Read);
    }

    public long GetFileSize(string path)
    {
        string fullPath = GetFullPath(path);
        return _fs.GetFileSizeSync(fullPath);
    }
}
#endif